import java.util.Vector;

public class Memory
{
	private static final int MEMORY_SIZE = (int) Math.pow(2, 12);
	private int Used_Memory;
	private int Free_Memory; 
	
	protected Vector<Integer> memory;
	
	public Memory() {
		memory = new Vector<Integer>(MEMORY_SIZE);
		Free_Memory = MEMORY_SIZE;
		Used_Memory = 0;
	}
	
	public int getData(int index)
	{
 		if(index > MEMORY_SIZE && index < 0) return -1; //exception?
 		else return memory.elementAt(index);
	}
	
	public void DeleteData(int index)
	{
 		if(!(index > MEMORY_SIZE && index < 0))
 		{
 			memory.add(index, 0);
 			Used_Memory--;
 			Free_Memory++;
 		} 		
	}
	
	public void PutData(int index)
	{
 		if(!(index > MEMORY_SIZE && index < 0))
 		{
 			memory.add(index, 1);
 			Used_Memory++;
 			Free_Memory--;
 		} 		
	}
	
	public int haveSpace()
	{
		if(Free_Memory > 0) return 1;
		else return 0;
	}
	
	public boolean FreeAtPosition(int index)
	{
		if(getData(index) == 0) return true;
		else return false;
	}
	
	/*
	 * 
	LinkedList<SpaceMap> UsedSpace = new LinkedList<SpaceMap>();
	LinkedList<SpaceMap> FreeSpace = new LinkedList<SpaceMap>();
	 * 
	public int malloc(final int PID, final int space)
	{
		if(space < 0) return -1;
		if(space > Free_Memory) return -1;
		
		// first-fit
		for(SpaceMap block : FreeSpace)
		{
			if(block.length >= space)
			{
				SpaceMap new_block = new SpaceMap();
				new_block.PID = PID;
				new_block.length = space;
				new_block.startAddress = block.startAddress;
				UsedSpace.add(new_block);
				
				if(block.length == space)
				{
					FreeSpace.remove(block);
				}
				else
				{
					block.length -= space;
					block.startAddress += space;
				}
				
				Used_Memory += space;
				Free_Memory -= space;
				
				return new_block.startAddress;
			}
		}
		return -1;		
	}
	
	public void free(final int address)
	{
		for(SpaceMap block : UsedSpace)
		{
			if(block.startAddress == address)
			{				
				FreeSpace.add(block);
				UsedSpace.remove(block);
				
				Used_Memory -= block.length;
				Free_Memory += block.length;
			}
		}
	}
	
	Memory()
	{
		SpaceMap initial = new SpaceMap(0, MEMORY_SIZE);
		FreeSpace.add(initial);
	}
	
	public void defrag()
	{
		
	}
	
	public int getInteger(final int address)
	{
		if(address < MEMORY_SIZE) return memory[address];
		
		return -1; // put exception here
	}
	
	public void putInteger(final int value, final int address)
	{
		// first you have to run malloc to make the allocation and get the address 
		if(address < MEMORY_SIZE) memory[address] = value;
	}
	
	public int[] readSequential(final int numberOfAddresses, final int address)
	{
		int current_address = address;
		int read[] = new int[numberOfAddresses];
		
		for(int i = 0; i < numberOfAddresses; i++)
		{
			if(current_address++ < MEMORY_SIZE) read[i] = memory[current_address];
			else return read;
		}
		
		return read;
	}
	
	*/
	
	
}
